# coding=utf-8
def go_pay(request):
    """
        功能:支付宝支付功能支付
        请求示例:
            {
                "method":             # 请求支付宝时候请求方式，在此接口就是返回数据类型，get返回url，post返回html表单
                "base_id":             # 基础配置项id
                "config_id":           # 商品配置项id
                "pay_way":             # 支付方式，1代表pc支付，2代表h5支付
            }

    """
    args = request.QUERY.casts(method=str, base_id=int, config_id=int, pay_way=int)
    method = args.method or "GET"   # 请求支付宝时候请求方式，在此接口就是返回数据类型，get返回url，post返回html表单
    base_id = args.base_id           # 通过base_id 可以去数据库中查找对应的支付宝支付的基础配置信息
    config_id = args.config_id       # 商品配置项id    通过config_id 可以去数据库中查找对应的支付宝支付商品的基础配置信息
    pay_way = args.pay_way           # 支付方式，1代表pc支付，2代表h5支付
    if not all([base_id, config_id, pay_way]):
        return ajax.jsonp_fail(request, {}, message="缺少必要参数，请重试！！！！！！")
    if pay_way not in [1, 2]:
        return ajax.jsonp_fail(request, {}, message="参数有误请重新输入！！！！！！")
    result_base = db.default.alipay_base_config.get(id=base_id)
    result_goods = db.default.alipay_goods_config.get(id=config_id, alipay_config_id=base_id)
    if not all([result_base, result_goods]):
        return ajax.jsonp_fail(request, {}, message="参数有误！！！！！！")
    user_id = str(8888)
    random_int = str(random.randint(1000, 9999))
    time_now = int(time.time())
    order_no = str(time_now) + random_int + user_id   #生成 商户网站唯一订单号
    res = alipay_config(result_base, result_goods, order_no, pay_way, method)  # 初始化阿里支付
    result_data = db.default.pay_info.create(  #将支付信息存入库里
        tbkt_pay_no=order_no,
        price=result_goods.total_amount,
        goods_name=result_goods.subject,
        add_time=time_now,
        pay_time="",
        pay_state=2,
        third_account=result_base.seller_id,
        pay_type=4 if pay_way == 1 else 5
    )
    if not result_data:
        return ajax.jsonp_fail(request, {}, message="服务器开小车，请稍后再试")
    return ajax.jsonp_ok(request, {"data": res})



def alipay_config(result_base, result_goods, order_no, pay_way, method):
    """
    初始化阿里支付
    """
    clientConfig = AlipayClientConfig()                                             # 支付宝封装的配置文件，默认是RSA2加密,这个类可以自己定义
    clientConfig.app_id = result_base.appid                                         # 开发者应用id
    clientConfig.app_private_key = result_base.key.replace("\r\n", "\n")           # 开发者应用私钥
    # clientConfig.alipay_public_key = public_key                                   # 蚂蚁金服开放平台公钥，可以不传
    if pay_way == 1:
        model = AlipayTradePagePayModel()                                           # 业务参数初始化
        model.product_code = result_base.pc_product_code                            # 销售产品码，商家和支付宝签约的产品码
    else:
        model = AlipayTradeWapPayModel()                                            # 业务参数初始化
        model.product_code = result_base.h5_product_code                            # 销售产品码，商家和支付宝签约的产品码
    model.subject = result_goods.subject                                            # 商品的标题/交易标题
    model.body = result_goods.body                                                  # 对一笔交易的具体描述信息
    model.out_trade_no = order_no                                                   # 商户网站唯一订单号
    model.timeout_express = result_base.exp_time                                    # 订单最晚交易时间，超过关闭
    model.total_amount = result_goods.total_amount                                  # 订单交易金额
    if pay_way == 1:
        ali_request = AlipayTradePagePayRequest(biz_model=model)                    # 获取pc站支付请求
        ali_request.notify_url = result_base.pc_notify_url                          # 服务器通知地址
        ali_request.return_url = result_base.pc_return_url                          # 页面通知地址
    else:
        ali_request = AlipayTradeWapPayRequest(biz_model=model)                     # 获取wap站支付请求
        ali_request.notify_url = result_base.h5_notify_url                          # 服务器通知地址
        ali_request.return_url = result_base.h5_return_url                          # 页面通知地址
    client = DefaultAlipayClient(alipay_client_config=clientConfig)
    response_url = client.page_execute(ali_request, http_method=method)
    return response_url




def notify(request):
    """
    支付宝内部支付完成后，异步通知到这个接口，返回支付宝状态，同步到数据库中
    """
    """处理不同得参数，必须返回success"""
    trade_no = request.POST.get("trade_no")              # 支付宝交易号
    out_trade_no = request.POST.get("out_trade_no")      # 获取订单号
    trade_status = request.POST.get("trade_status")      # 交易状态
    notify_id = request.POST.get("notify_id")            # 获取notify_id
    seller_id = request.POST.get("seller_id")            # 获取seller_id
    buyer_email = request.POST.get("buyer_logon_id")    # 获取支付者email
    total_amount = request.POST.get("total_amount")     # 获取支付价格
    # 获取当前价格订单在自己数据库是否存在
    pay_info = db.default.pay_info.get(tbkt_pay_no=out_trade_no, price=total_amount)
    if not pay_info:
        return HttpResponse('fail')
    # 对回传的seller_id做校验，确保向支付宝确认的seller_id是自己的
    if pay_info.third_account != seller_id:
        return HttpResponse('fail')
    # 状态trade_status = TRADE_SUCCESS说明是交易成功
    if trade_status == 'TRADE_SUCCESS':
        gateway = "http://notify.alipay.com/trade/notify_query.do?"
        veryfy_url = "partner=%s&notify_id=%s" % (seller_id, notify_id)
        url = gateway + veryfy_url
        try:
            resp = requests.urlopen(url)
            str_result = resp.read()
        except Exception as e:
            str_result = u"false"
        if str_result == b'true':
            time_now = int(time.time())
            # 更新数据库，此处还应在开通表增加数据
            result = db.default.pay_info.filter(tbkt_pay_no=out_trade_no).update(
                third_pay_no=trade_no, pay_state=1, pay_time=time_now, third_account=buyer_email)
            if not result:
                print("更新支付宝支付状态失败，订单号%s" % out_trade_no)
                return HttpResponse('fail')
            return HttpResponse('success')
        else:
            return HttpResponse('fail')
    else:
        return HttpResponse('success')
